package com.syqc.sensor.demp

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.github.mikephil.charting.data.Entry
import com.syqc.comlib.auto.AutoDisposeViewModel
import com.syqc.comlib.utils.AppContext
import com.syqc.comlib.utils.GsonUtil
import com.syqc.entity.KeyValue
import com.syqc.entity.ListItem
import com.syqc.entity.TypeInfo
import com.syqc.monitor.R
import com.syqc.utils.DataUtil
import kotlin.concurrent.thread

/**
 *@author  hfjs
 *@time   2024/11/8 17:03
 *@desc
 */
class TempDampVM : AutoDisposeViewModel() {

    //选中的类型
    val chooseType = mutableListOf<TypeInfo>()

    //日期
    private val days = mutableListOf<String>()

    private val dayListMap = hashMapOf<String, MutableList<ListItem>>()

    //需要展示的列表数据
    private val _listLive = MutableLiveData<MutableList<ListItem>?>()
    val listLive: LiveData<MutableList<ListItem>?> = _listLive

    //时间列表
    private val _timeLive = MutableLiveData<MutableList<String>>()
    val timeLive: LiveData<MutableList<String>> = _timeLive

    //选中的类型
    private val _typeLive = MutableLiveData<MutableList<String>>()
    val typeLive: LiveData<MutableList<String>> = _typeLive


    //转换为简单日期对一个的数据
    private val nodeDayMap = HashMap<String, ArrayList<String>?>()
    private val allDay = AppContext.getDescById(R.string.desc_list_monitor_all)

    //选中的日期
    var day = allDay

    //单位
    var unit: String = ""

    //是否是里程
    var isMile = true

    //是否是图表
    var isChart = true

    //是否加载过
    var isLoad = false

    //全部数据
    val allListItem = mutableListOf<ListItem>()


    /**
     *  初始化选中的类型
     *
     */
    fun initTypes() {
        DataUtil.typeInfos?.sortBy { it.typeId }
        DataUtil.typeInfos?.forEach {
            if (chooseType.size < 6) {
                it.isChecked = true
            }
        }
        senChooseType()
    }

    private fun senChooseType() {
        chooseType.clear()
        DataUtil.typeInfos?.forEach {
            if (it.isChecked) chooseType.add(it)
        }
        val types = mutableListOf<String>()
        chooseType.forEach {
            types.add(it.typeName)
        }
        _typeLive.postValue(types)
    }


    //初始化加载数据
    fun initData() {
        handleData()
    }

    //刷新数据
    fun refresh() {
        senChooseType()
        handleData()
    }

    //获取一天的数据
    fun getOneDayData(day: String) {
        sendChartData(day)
        sendListDate(day)
    }

    //获取某天的数据
    private fun sendListDate(day: String) {
        this.day = day
        allListItem.clear()

        if (day == allDay) {
            val allList = mutableListOf<ListItem>()
            dayListMap.values.forEach {
                allList.addAll(it)
            }
            allListItem.addAll(allList)
            _listLive.postValue(allList)
        } else {
            val list = dayListMap[day]
            if (list != null)
                allListItem.addAll(list)
            _listLive.postValue(list)
        }
    }


    //处理全部数据
    private fun handleData() {
        days.clear()
        nodeDayMap.clear()
        dayListMap.clear()
        val nodeMap = DataUtil.tempNodeMap ?: return
        thread {
            val sorted = nodeMap.keys.reversed().sorted()
            sorted.forEach {
                val value = nodeMap[it]
                if (value != null && days.size <= 6) {
                    val time = it.substring(5)
                    days.add(time)
                    nodeDayMap[time] = value
                }
            }
            val allList = mutableListOf<ListItem>()
            days.forEach {
                val list = handOneDay(it)
                allList.addAll(list)
                dayListMap[it] = list
            }
            days.add(0, allDay)
            if (day == allDay) _timeLive.postValue(days)
            sendChartData(day)
            sendListDate(day)
        }

    }


    /**
     * 处理一天的数据
     *
     * @param day
     * @return
     */
    private fun handOneDay(day: String): MutableList<ListItem> {
        if (nodeDayMap.isEmpty()) return mutableListOf()
        val dayData = mutableListOf<ListItem>()
        nodeDayMap[day]?.forEach { value ->
            val itemMap = GsonUtil.formJsonStrMap(value)
            var time = itemMap["time"].toString()
            if (time.length > 5) time = time.substring(5)
            val list = mutableListOf<KeyValue>()
            chooseType.forEach {
                list.add(KeyValue(it.typeId, itemMap["v${it.typeId}"] ?: ""))
            }
            val mile = ((itemMap["mile"] ?: "0").toInt() / 1000).toFloat()
            val speed = (itemMap["s"] ?: "0").toFloat()

            dayData.add(ListItem(time, mile, speed, list))
        }
        return dayData
    }


    ////////////////////////////////////////chart///////////////////////////////////////

    private val _entryLive = MutableLiveData<HashMap<String, MutableList<Entry>>>()
    val entryLive: LiveData<HashMap<String, MutableList<Entry>>> = _entryLive

    private val typeInfoMap = hashMapOf<String, MutableList<Entry>>()
    private fun resetMap() {
        times.clear()
        typeInfoMap.clear()
        typeInfoMap["-1"] = mutableListOf<Entry>()
        typeInfoMap["-2"] = mutableListOf<Entry>()
        chooseType.forEach {
            typeInfoMap[it.typeId] = mutableListOf<Entry>()
        }
    }


    //发送图表数据
    private fun sendChartData(day: String) {
        allListItem.clear()
        this.day = day
        if (day == allDay) {
            val allList = mutableListOf<ListItem>()
            dayListMap.values.forEach {
                allList.addAll(it)
            }
            allListItem.addAll(allList)
            handChart(allList)
            _entryLive.postValue(typeInfoMap)
        } else {
            val list = dayListMap.get(day)
            handChart(list)
            if (list != null)
                allListItem.addAll(list)
            _entryLive.postValue(typeInfoMap)
        }
    }

    val times = ArrayList<String>()

    private fun handChart(infos: MutableList<ListItem>?) {
        resetMap()
        infos?.forEachIndexed { index, info ->
            times.add(info.time.substring(6))
            val indexF = index.toFloat()
            typeInfoMap["-1"]?.add(Entry(indexF, info.mile))
            typeInfoMap["-2"]?.add(Entry(indexF, info.speed))
            info.list.forEach {
                typeInfoMap[it.key]?.add(
                    Entry(
                        indexF,
                        if (it.value.isEmpty()) 0f else it.value.toFloat()
                    )
                )
            }
        }

    }

    override fun onCleared() {
        super.onCleared()
        typeInfoMap.clear()
        nodeDayMap.clear()
    }

}



